#!/usr/bin/python

""" WebSsh Server """
""" Released under the GPL 3.0 by Laurent Grousset """

version = "0.0.1"

import os, sys, pwd, optparse

from SecureHTTPServer import SecureHTTPServer
from WebShellRequestHandler import WebShellRequestHandler

try:
    openssl_installed = False
    from OpenSSL import SSL
    openssl_installed = True
except ImportError:
    pass

#os.chdir(os.path.normpath(os.path.dirname(__file__)))
# Optional: Add QWeb in sys path
#sys.path[0:0] = glob.glob('../../python')


def main():
	parser = optparse.OptionParser()
	parser.add_option("-v", action = "store_true", dest = "version", default = "", 
		help = "show version number")
	parser.add_option("-i", dest = "interface", default = "", 
		help = "set listen interface (default: 0.0.0.0)")
	parser.add_option("-p", dest = "port", default = "8022", 
		help = "set listen port (default: 8022)")
	parser.add_option("-c", dest = "cmd", default = None, 
		help = "set shell command (default: ssh localhost)")
	parser.add_option("-t", dest = "term", default = "xterm-color",
		help = "set terminal emulation string (default: xterm-color)")
	parser.add_option("-l", action = "store_true", dest = "log", default = 0, 
		help = "output connection log to stderr (default: quiet)")
	parser.add_option("-d", action = "store_true", dest = "daemon", default = 0, 
		help = "run as daemon in the background")
	parser.add_option("-P", dest = "pidfile", default = "/var/run/webshell.pid",
		help = "set pidfile (default: /var/run/webshell.pid)")
	parser.add_option("-u", dest = "uid", 
		help = "set daemon user id")
	parser.add_option("--ssl-disable", action = "store_false", dest = "ssl_enabled", default = 1,
		help = "disable SSL, set listen interface to localhost")
	parser.add_option("--ssl-cert", dest = "ssl_cert", default = "webshell.pem",
		help = "set SSL certificate file (default: webshell.pem)")
 	parser.add_option("--www-dir", dest = "www_dir", default = "www",
		help = "set WebShell www path (default: www)")
	(o, a) = parser.parse_args()
	if o.version:
		print 'WebShell ' + version
		sys.exit(0)
	# Parameter validation
	try:
		o.port = int(o.port)
	except ValueError:
		print 'Invalid parameters'
		sys.exit(0)
	if (not openssl_installed) & o.ssl_enabled:
		print 'The python SSL extensions seem to be not installed.'
		print 'You can run WebShell without SSL encryption with the --ssl-disable command line switch.'
		sys.exit(0)
	if not o.ssl_enabled:
		if len(o.interface) == 0:
			o.interface='localhost'
	# Daemon mode
	if o.daemon:
		pid = os.fork()
		if pid == 0:
#			os.setsid() ?
			os.setpgrp()
			nullin = file('/dev/null', 'r')
			nullout = file('/dev/null', 'w')
			os.dup2(nullin.fileno(), sys.stdin.fileno())
			os.dup2(nullout.fileno(), sys.stdout.fileno())
			os.dup2(nullout.fileno(), sys.stderr.fileno())
			if os.getuid() == 0 and o.uid:
				try:
					os.setuid(int(o.uid))
				except:
					os.setuid(pwd.getpwnam(o.uid).pw_uid)
		else:
			try:
				file(o.pidfile, 'w+').write(str(pid) + '\n')
			except:
				pass
			sys.exit(0)
	# Run server
	try:
		server_address = (o.interface, o.port)
		httpd = SecureHTTPServer(server_address, WebShellRequestHandler, o.cmd, o.term, o.ssl_enabled, o.ssl_cert, o.www_dir)
		if httpd.socket is None:
			print 'There is a problem with OpenSSL. Make sure the certificates\' path and content are correct.'
			sys.exit(0)
		sa = httpd.socket.getsockname()
		if not o.daemon:
			scheme = 'http'
			if o.ssl_enabled:
				scheme += 's'
			print 'WebShell (%s) at %s, port %s' % (scheme, sa[0], sa[1])
		httpd.serve_forever()
	except KeyboardInterrupt:
		httpd.stop()
		print 'Stopped'

if __name__ == '__main__':
	main()
